<?php
/*
+--------------------------------------------------------------------------
|   IKPHP [#RELEASE_VERSION#]
|   ========================================
|   By IKPHP Software
|   © 2013 - 2050 WeCenter. All Rights Reserved
|   http://www.ikphp.com
|   ========================================
|   Author: 小麦 <ikphp@sina.cn>
+---------------------------------------------------------------------------
*/
defined ( 'IN_IKPHP' ) or exit ( 'WebSite Access Denied' );
class IKPHP
{
    // 类映射
    private static $_map      = array();	
    // 实例化对象
    private static $_instance = array();    
    /**
     * 应用程序初始化
     * @access public
     * @return void
     */	
	static public function start() { 
		// 设定错误和异常处理
		set_exception_handler(array('IKPHP', 'handleException'));
		set_error_handler(array('IKPHP', 'handleError'));
		register_shutdown_function(array('IKPHP', 'handleShutdown'));
				
		// 注册AUTOLOAD方法
		spl_autoload_register('IKPHP::autoload');   

		// 初始化文件存储方式
      	memory::connect(MEMORY_TYPE);
      	$runtimefile  = RUNTIME_PATH.APP_MODE.'~runtime.php';
		if(!APP_DEBUG && memory::has($runtimefile)){
			memory::load($runtimefile);
		}else{ 
      		if(memory::has($runtimefile))
            memory::unlink($runtimefile);
            
            $content =  '';
                
             // 读取应用模式
			if(!defined('IKPHP_CORE_MODE') && !is_file(IKPHP_PATH.'config/'.APP_MODE.'.php')) {
				throw new Exception(APP_MODE.'.php is missing');
			}else{
				$mode   =   include IKPHP_PATH.'config/'.APP_MODE.'.php';
			}    
     
		    // 加载核心文件
          	foreach ($mode['core'] as $file){ 
              	if(is_file($file)) {
                	include $file;
                	if(!APP_DEBUG) $content   .= compile($file);
              	}
          	}
          	
		    // 加载应用模式配置文件
          	foreach ($mode['config'] as $key=>$file){
              	is_numeric($key)?C(include $file):C($key,include $file);
          	}

		     // 加载模式行为定义
          	if(isset($mode['tags'])) {
              	hook::import(is_array($mode['tags'])?$mode['tags']:include $mode['tags']);
          	}          	

             // 加载应用行为定义
            if(is_file(CONF_PATH.'tags.php')){
              // 允许应用增加开发模式配置定义
              hook::import(include CONF_PATH.'tags.php');
            }            	
		    // 加载框架底层语言包
            L(include IKPHP_PATH.'lang/'.strtolower(C('DEFAULT_LANG')).'.php');
          	if(!APP_DEBUG){
                $content  .=  "\nIKPHP::addMap(".var_export(self::$_map,true).");"; 
                $content  .=  "\nL(".var_export(L(),true).");\nC(".var_export(C(),true).');hook::import('.var_export(hook::get(),true).');';
                memory::put($runtimefile,strip_whitespace('<?php '.$content));               
          	}else{
	             // 调试模式加载系统默认的配置文件
	            C(include IKPHP_PATH.'config/debug.php');         		
          	}          				
		} 
		 
		// 设置系统时区
		date_default_timezone_set(C('DEFAULT_TIMEZONE'));   
		
		//检查来源
		define('IS_ROBOT', checkrobot()); 
		
		// 记录加载文件时间
		G('loadTime');	
		// 运行应用
		application::run();
		return ;	
	}
	/**
     * 类库自动加载
     * @param string $class 对象类名
     * @return void
     */
    public static function autoload($class) { 
    	$class = strtolower($class); 
    	$path = 'system/class/';
		
    	if(strpos($class, '_') !== false) {
			list($folder) = explode('_', $class);
			//自动加载common层的controller; model;library 类不允许内部继承
			if($folder == 'controller' || $folder == 'tag'){
				$path = 'apps/common/';
			}
			$file = $path.$folder.'/'.substr($class, strlen($folder) + 1); 
		} else {
			$file = $path.$class;
		}
	
		try {
			self::import($file);
			return true;
		} catch (Exception $exc) {
			$trace = $exc->getTrace();
			foreach ($trace as $log) {
				if(empty($log['class']) && $log['function'] == 'class_exists') {
					return false;
				}
			}
			exceptions::exception_error($exc);
		}
    }
	/**
	 * 导入所需的类库  
	 * @param string $name   类库命名空间字符串
	 * @param string $folder 起始路径 必须带/
	 * @param string $force  
	 * @return boolean
	 */    
	public static function import($name, $folder = '', $force = true) {
		$key = $folder.$name; 
		if(!isset(self::$_map[$key])) { 
			$path = SITE_PATH.$folder; 
			if(strpos($name, '/') !== false) {
				$pre = basename(dirname($name));
				$filename = dirname($name).'/'.$pre.'_'.basename($name).'.php';
			} else {
				$filename = $name.'.php';
			}

			if(is_file($path.$filename)) {
				include $path.$filename; 
				self::$_map[$key] = true;

				return true;
			} elseif(!$force) {
				return false;
			} else {
				throw new Exception('Oops! System file lost: '.$filename);
			}
		}
		return true;
	}
	// 例外捕捉 
	public static function handleException($exception) {
		exceptions::exception_error($exception);
	}
	// 系统错误
	public static function handleError($errno, $errstr, $errfile, $errline) {		
		exceptions::system_error($errno, $errstr, $errfile, $errline);
	}
	// 致命错误捕捉
	public static function handleShutdown() {
		exceptions::shutdown_error();
	}
    // 注册classmap
    static public function addMap($class, $map=''){
        if(is_array($class)){
            self::$_map = array_merge(self::$_map, $class);
        }else{
            self::$_map[$class] = $map;
        }        
    }
    // 获取classmap
    static public function getMap($class=''){
        if(''===$class){
            return self::$_map;
        }elseif(isset(self::$_map[$class])){
            return self::$_map[$class];
        }else{
            return null;
        }
    }
    /**
     * 取得对象实例 支持调用类的静态方法
     * @param string $class 对象类名
     * @param string $method 类的静态方法名
     * @return object
     */
    static public function instance($class,$method='') { 
        $identify   =   $class.$method;
        if(!isset(self::$_instance[$identify])) {
            if(class_exists($class)){
                $o = new $class();
                if(!empty($method) && method_exists($o,$method))
                    self::$_instance[$identify] = call_user_func(array(&$o, $method));
                else
                    self::$_instance[$identify] = $o;
            }
            else
              E('Class Not Exist: '.$class);
        }
        return self::$_instance[$identify];
    }
    /**
     * 添加和获取页面Trace记录
     * @param string $value 变量
     * @param string $label 标签
     * @param string $level 日志级别(或者页面Trace的选项卡)
     * @param boolean $record 是否记录日志
     * @return void
     */
    static public function trace($value='[ikphp]',$label='',$level='DEBUG',$record=false) {
        static $_trace =  array();
        if('[ikphp]' === $value){ // 获取trace信息
            return $_trace;
        }else{
            $info   =   ($label?$label.':':'').print_r($value,true);
            $level  =   strtoupper($level);
            
            if((defined('IS_AJAX') && IS_AJAX) || !C('SHOW_PAGE_TRACE')  || $record) {
                //log::record($info,$level,$record);
            }else{
                if(!isset($_trace[$level]) || count($_trace[$level])>C('TRACE_MAX_RECORD')) {
                    $_trace[$level] =   array();
                }
                $_trace[$level][]   =   $info;
            }
        }
    }            			   
}
